﻿using auto_win;
using FlaUI.Core.AutomationElements;
using FlaUI.Core.Conditions;
using FlaUI.Core.Definitions;
using FlaUI.Core.Input;
using FlaUI.Core.Tools;
using FlaUI.Core.WindowsAPI;
using FlaUI.UIA3;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Application = FlaUI.Core.Application;

namespace auto_chat_win
{
    internal class WechatMgr
    {
        private const string appName = "微信";
        private List<WechatApplication> apps = new List<WechatApplication>();
        private UIA3Automation auto = new UIA3Automation();
        private ConditionFactory cf = new ConditionFactory(new UIA3PropertyLibrary());
        private MainForm form;
        private int wait_minutes = 1000;

        public WechatMgr(MainForm form) 
        { 
            this.form = form;
        }


        //扫描微信窗口
        public List<WechatApplication> ScanWechatProcess(Dictionary<string, WechatApplication> dict)
        {
            apps.Clear();
            Trace.WriteLine("---------开始扫描" + appName + "-----------");
            var desktop = auto.GetDesktop();
            var all = desktop.FindAllChildren();

            foreach (var child in all)
            {
                var win = child.AsWindow();
                
                var name = child.Name;
                if (appName.Equals(name))
                {
                    string nickname = GetWechatInfo(win);
                    Trace.WriteLine("发现窗口：" + name + " 微信名称：" + nickname);
                    if(nickname == null)
                    {
                        continue;
                    }
                    WechatApplication wechatApp;
                    var has = dict.TryGetValue(nickname, out wechatApp);
                    if (has)
                    {
                        wechatApp.processId = win.Properties.ProcessId;
                        wechatApp.app = Application.Attach(wechatApp.processId);
                        wechatApp.wechatAccount = nickname;
                        apps.Add(wechatApp);
                    }
                }
            }
            return apps;
        }

        private AutomationElement GetMainPane(Window win)
        {
            if (win.Patterns.Window.Pattern.WindowVisualState == WindowVisualState.Minimized)
            {
                win.Patterns.Window.Pattern.SetWindowVisualState(WindowVisualState.Normal);
            }
            win.Focus();
            //主面板，它由三个子组件从左到右构成：导航、用户列表、对话框
            //如果最小化，只有一个子组件，否则有两个
            var items = win.FindAllChildren();
            var wrapper = items[items.Length - 1];
            var mainPanel = wrapper.FindChildAt(0);
            return mainPanel;
        }

        //扫描好朋友
        public List<CrowdMember> ScanNewFriends(WechatApplication app)
        {
            var accounts = new List<CrowdMember>();
            var win = app.app.GetMainWindow(auto);
            win.Focus();
            var toolBar = GetMainPane(win).FindChildAt(0);
            var wxBtn = toolBar.FindChildAt(2); //导航栏的联系人按钮
            wxBtn.Click();
            Thread.Sleep(wait_minutes);
            var middlePane = GetMainPane(win).FindChildAt(1);
            var contactBtn = middlePane.FindChildAt(1).FindChildAt(0).FindChildAt(0).FindFirstChild(cf.ByName("新的朋友"));
            contactBtn.Click();
            Thread.Sleep(wait_minutes);
            var rightPane = GetMainPane(win).FindChildAt(2);
            try
            {
                var backBtn = rightPane.FindChildAt(0).FindChildAt(0).FindChildAt(0); //查看好友资料的界面
                if (backBtn.ControlType == ControlType.Button)
                {
                    backBtn.Click();
                }
            }
            catch (Exception ex) { };
            var friendsListResult = Retry.WhileNull<AutomationElement>(() =>
            {
                return rightPane.FindFirstDescendant(cf.ByControlType(ControlType.List).And(cf.ByName("新的朋友")));
            }, TimeSpan.FromSeconds(2));
            if (friendsListResult.Result != null)
            {
                foreach(var item in friendsListResult.Result.FindAllChildren())
                {
                    var basePane = item.FindChildAt(0);
                    var acceptBtn = basePane.FindChildAt(2);
                    if(acceptBtn.Name == "接受")
                    {
                        var introduce = basePane.FindChildAt(1).FindChildAt(1).FindChildAt(0); //自我介绍
                        CrowdMember acc = new CrowdMember();
                        var text = introduce.Name.Trim();
                        if (text.StartsWith("我是群聊“") || text.StartsWith("我是群聊\""))
                        {
                            var endAt = text.IndexOf("”的", 5);
                            if(endAt == -1)
                            {
                                endAt = text.IndexOf("\"的", 5);
                            }
                            acc.crowdname = text.Substring(5, endAt - 5);
                            acc.nickname = item.Name;
                            var prefix = getPrefixNumber(acc.crowdname);
                            acc.comment = prefix + acc.nickname;
                            acceptBtn.Click();

                            Thread.Sleep(wait_minutes);
                            var confirmPane = win.FindChildAt(0).FindChildAt(1);
                            var mainPane = confirmPane.FindChildAt(0).FindChildAt(0).FindChildAt(1);
                            //修改备注
                            var nameInput = mainPane.FindChildAt(0).FindChildAt(1).FindChildAt(0);
                            nameInput.Click();
                            Keyboard.Press(VirtualKeyShort.HOME);
                            PasteContent(prefix);
                            Thread.Sleep(wait_minutes);

                            //5000+好友以上账号
                            var checkBox = mainPane.FindFirstDescendant(cf.ByControlType(ControlType.Text).And(cf.ByName("朋友圈")));
                            if (checkBox != null)
                            {
                                checkBox.Click();
                            }
                            Thread.Sleep(wait_minutes);
                            var confirmBtn = confirmPane.FindChildAt(1).FindChildAt(0);
                            confirmBtn.Click();
                            // 等待2类结果，已过期或添加成功
                            Retry.WhileFalse(() =>
                            {
                                var dialogWin = win.FindChildAt(0);
                                //if (dialogWin.ControlType == ControlType.Window)
                                if (dialogWin.Properties.ClassName.IsSupported && dialogWin.ClassName == "WeUIDialog")
                                {
                                    Trace.WriteLine("加入好友已过期");
                                    var btn = dialogWin.FindFirstDescendant(cf.ByControlType(ControlType.Button));
                                    btn.Click();
                                    return true;
                                }

                                try
                                {
                                    basePane = item.FindChildAt(0);
                                    acceptBtn = basePane.FindChildAt(2);
                                    if (acceptBtn.Name == "已添加")
                                    {
                                        acceptBtn.Click();
                                        var detailPane = rightPane.FindChildAt(0).FindChildAt(1).FindChildAt(0).FindChildAt(0).FindChildAt(0); //查看好友资料的界面
                                        var wechatId = detailPane.FindChildAt(1).FindChildAt(1).FindFirstDescendant(cf.ByName("微信号：")).Parent.FindChildAt(1).Name;
                                        acc.wechatId = wechatId;
                                        var backBtn = rightPane.FindChildAt(0).FindChildAt(0).FindChildAt(0); //查看好友资料的界面的后退按钮
                                        backBtn.Click();
                                        Trace.WriteLine($"加我好友：{acc.crowdname}, {acc.wechatId}");
                                        accounts.Add(acc);
                                        return true;
                                    }
                                }
                                catch(Exception ex) { }

                                return false;
                            }, TimeSpan.FromSeconds(5));
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            return accounts;
        }

        //扫描群消息
        public List<string> ScanNewMessage(WechatApplication app, string sender, out int count)
        {
            var joins = new List<string>();
            var win = app.app.GetMainWindow(auto);
            var success = OpenDialog(win, sender);
            if (success)
            {
                var rightPane = GetMainPane(win).FindChildAt(2);
                var nicknameBtn = rightPane.FindFirstDescendant(cf.ByControlType(ControlType.Button));
                var countLabel = nicknameBtn.Parent.FindChildAt(0).FindChildAt(1);
                var name = countLabel.Name.Trim();
                count = Int16.Parse(name.Substring(1, name.Length - 2));
                Trace.WriteLine("count=" + count);

                var sendPane = GetSendPane(rightPane);
                var msgList = sendPane.FindChildAt(0).FindFirstDescendant(cf.ByControlType(ControlType.List));
                if(msgList != null)
                {
                    foreach (var i in msgList.FindAllChildren())
                    {
                        var pane = i.FindChildAt(0);
                        if(pane.ControlType == ControlType.Pane)
                        {
                            var text = pane.FindChildAt(1);
                            if(text.ControlType == ControlType.Text)
                            {
                                joins.Add(text.Name.Trim());
                            }
                        }
                    }
                }
            }
            else
            {
                count = 0;
            }
            return joins;

        }

       
        //获取自己的微信昵称
        private string GetWechatInfo(Window win)
        {
            var toolBar = GetMainPane(win).FindChildAt(0);
            var wxBtn = toolBar.FindChildAt(0);
            var point = wxBtn.GetClickablePoint();
            //定位到个人头像
            Mouse.Click(point);
            Thread.Sleep(wait_minutes);
            var nicknameResult = Retry.WhileNull<string>(() =>
            {
                var children = win.FindChildAt(0).FindAllDescendants(cf.ByControlType(ControlType.Text));
                if(children.Length >= 1)
                {
                    return children[0].Name;
                }
                return null;
            }, TimeSpan.FromSeconds(2));
            if(nicknameResult.Result != null)
            {
                var nickname = nicknameResult.Result;
                point.Y -= 20;
                Mouse.Click(point);
                return nickname;
            }
            return null;
        }

        //包括右边消息框和发送框
        private AutomationElement GetSendPane(AutomationElement rightPane)
        {
            return rightPane.FindChildAt(0).FindChildAt(0).FindChildAt(0).FindChildAt(0).FindChildAt(1);
        }
        //只有发送框
        private AutomationElement GetSendPaneOnly(AutomationElement sendPane)
        {
            return sendPane.FindChildAt(1).FindChildAt(1).FindChildAt(0);
        }

        public bool SendMessage(WechatApplication app, string content, string receiver, bool atAll)
        {
            Trace.WriteLine($"发送消息“{content}”给“{receiver}”");
            var win = app.app.GetMainWindow(auto);
            var success = OpenDialog(win, receiver);
            if (success)
            {
                var rightPane = GetMainPane(win).FindChildAt(2);
                var sendPane = GetSendPane(rightPane);
                var sendPaneOnly = GetSendPaneOnly(sendPane);
                var input = sendPaneOnly.FindChildAt(1).FindChildAt(0);
                Trace.WriteLine($"发送群消息{input}");
                if (input.Name == receiver)
                {
                    input.Focus();
                    if (atAll)
                    {
                        using (Keyboard.Pressing(VirtualKeyShort.SHIFT)) {
                            Keyboard.Type(VirtualKeyShort.KEY_2);
                            Wait.UntilInputIsProcessed();
                        }
                        Thread.Sleep(wait_minutes);
                        Retry.WhileFalse(() =>
                        {
                            try
                            {
                                var menu = win.FindChildAt(0);
                                if (menu.Name == "ChatContactMenu")
                                {
                                    var all = menu.FindChildAt(1).FindChildAt(0).FindChildAt(0);
                                    all.Click();
                                    Thread.Sleep(wait_minutes);
                                    return true;
                                }
                            }
                            catch (Exception ex)
                            { }
                            return false;
                        });
                    }
                    PasteContent(content);
                    Thread.Sleep(wait_minutes);
                    sendPaneOnly.FindChildAt(2).FindFirstDescendant(cf.ByControlType(ControlType.Button)).Click();
                    Thread.Sleep(wait_minutes);
                    return true;
                }
            }
            return false;
        }

        /// <summary>
                /// 从剪贴板粘贴内容
                /// </summary>
        private void PasteContent(string content)
        {
            System.Windows.Clipboard.SetText(content);
            Keyboard.Pressing(VirtualKeyShort.CONTROL);
            Keyboard.Press(VirtualKeyShort.KEY_V);
            Keyboard.Release(VirtualKeyShort.CONTROL);
        }

        //检查当前是否是目标网友的对话框，如果不是，就搜索找到它
        private bool OpenDialog(Window win, string receiver)
        {
            var toolBar = GetMainPane(win).FindChildAt(0);
            var wxBtn = toolBar.FindChildAt(1); //导航栏的微信按钮
            wxBtn.Click();
            Thread.Sleep(wait_minutes);
            var rightPane = GetMainPane(win).FindChildAt(2);
            var label = rightPane.FindFirstDescendant(cf.ByControlType(ControlType.Text));
            if (label != null && label.Name.Trim().Equals(receiver))
            {
                return true;
            }
            var item = Search(win, receiver);
            if (item != null)
            {
                item.Click();
                return true;
            }
            return false;
        }

        private AutomationElement Search(Window win, string receiver)
        {
            var target = findReceiver(win, receiver);
            if (target != null)
            {
                return target;
            }
            var searchEdit = GetMainPane(win).FindChildAt(1).FindFirstDescendant(cf.ByName("搜索")).AsTextBox();
            searchEdit.Click();
            PasteContent(receiver);
            Thread.Sleep(wait_minutes);
            var search = Retry.WhileNull(() =>
            {
                try
                {
                    var searchList = GetMainPane(win).FindChildAt(1).FindChildAt(1).FindChildAt(1).FindChildAt(0);
                    if(searchList.ControlType == ControlType.List)
                    {
                        var name = searchList.FindChildAt(0).FindChildAt(0).Name;
                        if (name == "联系人" || name == "群聊")
                        {
                            target = searchList.FindChildAt(1);
                            if(target.Name == receiver)
                            {
                                return target;
                            }
                        }
                    }
                }
                catch (Exception ex) { }
                return null;
            }, TimeSpan.FromSeconds(3));
            if (search.Result != null)
            {
                return search.Result;
            }
            return null;
        }

        private AutomationElement findReceiver(Window win, string receiver)
        {
            var toolBar = GetMainPane(win).FindChildAt(0);
            var wxBtn = toolBar.FindChildAt(1); //导航栏的微信按钮
            wxBtn.Click();
            Thread.Sleep(wait_minutes);
            var list = GetMainPane(win).FindFirstDescendant(cf.ByControlType(ControlType.List));
            var target = findChildByNameStartsWith(list, receiver);
            return target;
        }


        private AutomationElement findChildByNameStartsWith(AutomationElement ele, string name)
        {
            foreach (var item in ele.FindAllChildren())
            {
                if (item.Name.StartsWith(name))
                {
                    return item;
                }
            }
            return null;
        }

        private void PrintChild(AutomationElement ele, string prefix = "", bool cycle = false)
        {
            foreach (var item in ele.FindAllChildren())
            {
                try
                {
                    var name = prefix + " -> " + item.ToString();//prefix + "-> 1)" + item.Name + " 2)" + item.ClassName + " 3)" + item.AutomationId;
                    Trace.WriteLine(name);
                    if (cycle)
                    {               
                        PrintChild(item, name, true);                 
                    }
                }
                catch (Exception){}
            }
        }

        private string getPrefixNumber(string name)
        {
            var prefix = "";
            foreach(var ch in name)
            {
                if (Char.IsNumber(ch))
                {
                    prefix += ch;
                }
                else
                {
                    break;
                }
            }
            return prefix;
        }

        public string test(WechatApplication app)
        {
            var win = app.app.GetMainWindow(auto);
            win.Focus();
            var dialog = win.FindChildAt(1);

            return null;
        }
    }

}
